<template>
  <div class="login">
    <img class="logo" src="@/assets/images/jh.png">
    <img class="login-title" src="@/assets/images/login-title.png">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
      <!--<div class="title">
        <h3 >智能支撑保障系统</h3>
        <div class="version-container">
          <img src="@/assets/images/version.png" alt="" width="32px" height="16px">
        </div>
      </div>-->
      <el-form-item prop="username">
        <el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号">
          <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码"
          @keyup.enter.native="handleLogin">
          <svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
        </el-input>
      </el-form-item>
      <el-form-item prop="code" v-if="captchaEnabled">
        <el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%"
          @keyup.enter.native="handleLogin">
          <svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
        </el-input>
        <div class="login-code">
          <img :src="codeUrl" @click="getCode" class="login-code-img" />
        </div>
      </el-form-item>
      <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox>
      <el-form-item style="width:100%;">
        <el-button :loading="loading" size="medium" type="primary" style="width:100%;"
          @click.native.prevent="handleLogin">
          <span v-if="!loading">登 录</span>
          <span v-else>登 录 中...</span>
        </el-button>

        <!--
        <el-button class="thirdparty-button" type="primary" @click="beginRegister">
          注册
        </el-button>

        <el-button class="thirdparty-button" type="primary" @click="beginLogin">
          登录
        </el-button>>-->
        <div style="float: right;" v-if="register">
          <router-link class="link-type" :to="'/register'">立即注册</router-link>
        </div>
      </el-form-item>
    </el-form>
    <!--  底部  -->
    <div class="el-login-footer">
      <!--      <span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span>-->
    </div>
  </div>
</template>

<script>
import { getCodeImg, login } from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'
import { register, registerVerify, loginUkeyVerify } from "@/api/system/user";
import webauthn from "@/assets/js/webauthn"
import { option } from "runjs";

export default {
  name: "Login",
  data() {
    return {
      codeUrl: "",
      loginForm: {
        username: "",
        password: "",
        rememberMe: false,
        code: "",
        uuid: ""
      },
      loginRules: {
        username: [
          { required: true, trigger: "blur", message: "请输入您的账号" }
        ],
        password: [
          { required: true, trigger: "blur", message: "请输入您的密码" }
        ],
        code: [{ required: true, trigger: "change", message: "请输入验证码" }]
      },
      loading: false,
      // 验证码开关
      captchaEnabled: true,
      // 注册开关
      register: false,
      redirect: undefined,
      usbDevice: null
    };
  },
  watch: {
    $route: {
      handler: function (route) {
        this.redirect = route.query && route.query.redirect;
      },
      immediate: true
    }
  },
  created() {
    this.getCode();
    this.getCookie();
  },
  methods: {
    getCode() {
      getCodeImg().then(res => {
        this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;
        if (this.captchaEnabled) {
          this.codeUrl = "data:image/gif;base64," + res.img;
          this.loginForm.uuid = res.uuid;
        }
      });
    },
    getCookie() {
      const username = Cookies.get("username");
      const password = Cookies.get("password");
      const rememberMe = Cookies.get('rememberMe')
      this.loginForm = {
        username: username === undefined ? this.loginForm.username : username,
        password: password === undefined ? this.loginForm.password : decrypt(password),
        rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
      };
    },
    async handleLogin() {

      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true;
          if (this.loginForm.rememberMe) {
            Cookies.set("username", this.loginForm.username, { expires: 30 });
            Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });
            Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });
          } else {
            Cookies.remove("username");
            Cookies.remove("password");
            Cookies.remove('rememberMe');
          }

          const username = this.loginForm.username;
          const password = this.loginForm.password;
          const code = this.loginForm.code;
          const uuid = this.loginForm.uuid;

          login(username, password, code, uuid).then(res => {
            if (res.code === 200) {
              console.log(res.data);
              console.log(res.data.token);
              let token = res.data.token;
              let authType = res.data.authType
              if (authType == "fido") {
                // console.log(res.data.credentialOptions);
                let options = res.data.credentialOptions;
                console.log("options:" + JSON.stringify(options))

                this.authGetPublicKeyLocal(options).then((assertion) => {
                  console.log("assertion:" + JSON.stringify(assertion));

                  if (assertion) {
                    let challenge = options.challenge;
                    this.authLoginVerifyServer(assertion).then((response) => {
                      console.log("response:" + JSON.stringify(response));
                      if (response.code == 200) {
                        console.log("登录成功:" + token);
                        this.$store.dispatch("Login", token)
                        this.$router.push({ path: "/" }).catch(() => {
                          console.log("catch");
                        });
                      }
                    }).catch((err) => {
                      console.log("err:" + JSON.stringify(err));
                      this.loading = false;
                    });

                    // this.authLoginVerifyServer(challenge, assertion).then((response) => {
                    //   console.log("response:"+JSON.stringify(response));
                    // });
                  }
                });
              } else {
                this.$store.dispatch("Login", res.data.token)
                this.$router.push({ path: "/" }).catch(() => { });
              }
            } else {
              this.getCode();
              this.loading = false;
            }
          }).catch(() => {
            this.getCode();
            this.loading = false;
          })


          // this.$store.dispatch("Login", this.loginForm).then((res) => {
          //   let options = res.credentialOptions;
          //   console.log(JSON.stringify(options));

          //   // this.authGetPublicKeyLocal(options).then((assertion) => {
          //   //   console.log("assertion:"+JSON.stringify(assertion));
          //   //   if (assertion) {
          //   //     let challenge = options.challenge;
          //   //     this.authLoginVerifyServer(challenge, assertion).then((response) => {
          //   //       // console.log("response:"+JSON.stringify(response));
          //   //     });
          //   //   }
          //   // });


          //   // this.$router.push({path: "/"}).catch(() => {});
          // }).catch(() => {
          //   this.loading = false;
          //   console.log("error submit!!");
          //   if (this.captchaEnabled) {
          //     this.getCode();
          //   }
          // });
        }
      });
    },

    /* 向服务端获取认证结果 */
    async authLoginVerifyServer(assertion) {
      const transformedAssertionForServer = webauthn.transformAssertionForServer(assertion);

      console.log("transformedAssertionForServer:" + JSON.stringify(transformedAssertionForServer));

      return loginUkeyVerify(transformedAssertionForServer)

      // try {
      //   let url = URL.LOG_VERIFY;
      //   response = await this.postAssertionToServer(url, transformedAssertionForServer);
      // } catch (err) {
      //     this.$message.warning("认证失败");
      // }
      // return response;
    },

    async beginRegister() {
      this.userName = "admin";
      let data = {
        userName: "admin"
      };
      let options = undefined;

      if (data.userName) {
        register(data.userName).then((res) => {
          if (res.code === 200) {
            options = res.data.data
            let challenge = options.challenge.value;
            let user_name = options.user.name;
            let user_key = res.data.userKey;

            console.log("options:" + JSON.stringify(options));
            // let options = {
            //   "rp": {
            //   "id": "localhost",
            //   "name": "localhost"
            //   },
            //   "user": {
            //   "id": "dXNlcl9pZA==",
            //   "name": "john_doe",
            //   "displayName": "john_doe"
            //   },
            //   "pubKeyCredParams": [
            //   { "type": "public-key", "alg": -7 },
            //   { "type": "public-key", "alg": -257 }
            //   ],
            //   "authenticatorSelection": {
            //   "authenticatorAttachment": "cross-platform",
            //   "userVerification": "preferred"
            //   },
            //   "challenge": "7a1cNQKtx3YN5JVemYIh5w==",
            //   "allowCredentials": [{
            //   "id": "YWxsb3dfY3JlZGVudGlhbA==",
            //   "type": "public-key"
            // }]
            // };

            this.authCreatePublicKeyLocal(options).then((credential) => {
              if (credential) {
                this.authRegisterVerifyServer(challenge, user_name, user_key, credential).
                  then((response) => {
                    console.log("OK")
                  }).catch((err) => {
                    console.log(err);
                  });
              } else {
                console.log("获取本地认证失败");
                // this.loading = false;}
              }
            });

          } else {
            this.$message.error(res.errorMsg)
          }
        }).catch((err) => {
          console.log(err);
        })

      } else if (!this.username) {
        this.$message.warning('请输入账号!');
      }
    },

    async authGetOptionsServer(url, data) {
      this.loading = true;
      return await webauthn.fetch_json(url, {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
          "Content-Type": "application/json"
        },
      });
    },



    async authGetPublicKeyLocal(options) {
      const transformedCredentialRequestOptions = webauthn.transformCredentialRequestOptions(
        options);
      let assertion;

      // const transformedCredentialRequestOptions = {"rp":{"id":"localhost","name":"localhost"},"user":{"id":{"0":117,"1":115,"2":101,"3":114,"4":95,"5":105,"6":100},"name":"john_doe","displayName":"john_doe"},"pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"authenticatorSelection":{"authenticatorAttachment":"cross-platform","userVerification":"preferred"},"challenge":{"0":237,"1":173,"2":92,"3":53,"4":2,"5":173,"6":199,"7":118,"8":13,"9":228,"10":149,"11":94,"12":153,"13":130,"14":33,"15":231},"allowCredentials":[{"id":"YWxsb3dfY3JlZGVudGlhbA==","type":"public-key"}]}
      // console.log("publicKeyCredentialRequestOptions:"+JSON.stringify(transformedCredentialRequestOptions));

      try {
        assertion = await navigator.credentials.get({
          publicKey: transformedCredentialRequestOptions,
        });
      } catch (err) {
        console.log(err);
        this.$message.warning("获取本地认证失败");
      }
      return assertion;
    },

    beginLogin() {
      let options = {
        "rp": {
          "id": "localhost",
          "name": "localhost"
        },
        "user": {
          "id": "dXNlcl9pZA==",
          "name": "john_doe",
          "displayName": "john_doe"
        },
        "pubKeyCredParams": [
          { "type": "public-key", "alg": -7 },
          { "type": "public-key", "alg": -257 }
        ],
        "authenticatorSelection": {
          "authenticatorAttachment": "cross-platform",
          "userVerification": "preferred"
        },
        "challenge": "7a1cNQKtx3YN5JVemYIh5w==",
        "allowCredentials": [{
          "id": "VVnFns4UcykXCWHWv7eyg1Osj0LOnZ4orofmKnaYsNC8RA9GEDuUuo442SpbMtztth25-gkvNCtqdTgk34k4UmaGu3A4bo4TA4upXhdODCD5LbXrXUp-5D62-l5UREAv",
          "type": "public-key"
        }]
      };

      console.log(options);
      this.authGetPublicKeyLocal(options).then((assertion) => {
        console.log("assertion:" + JSON.stringify(assertion));
      });

    },




    async authRegisterVerifyServer(challenge, user_name, user_key, credential) {

      const transformedAssertionForServer = webauthn.transformNewAssertionForServer(credential);

      //  console.log(JSON.stringify(credential));
      transformedAssertionForServer['challenge'] = challenge;
      transformedAssertionForServer['userKey'] = user_key;
      transformedAssertionForServer['userName'] = user_name;


      console.log("transformedAssertionForServer:" + JSON.stringify(transformedAssertionForServer))

      try {
        registerVerify(transformedAssertionForServer).then(res => {
          if (res.code === 200) {
            this.$message.success("注册认证成功");
          } else {
            this.$message.warning("注册认证失败");
          }
        });
      } catch (err) {
        this.$message.warning("认证失败");
      }
      return response;
    },

    async authCreatePublicKeyLocal(options) {
      const publicKeyCredentialCreateOptions = webauthn.transformCredentialCreateOptions(
        options);

      let credential;
      try {
        credential = await navigator.credentials.create({
          publicKey: publicKeyCredentialCreateOptions
        });
        console.log("本地电子Key:" + JSON.stringify(credential));

      } catch (err) {
        console.log(err);
        this.$message.warning("获取本地认证失败");
      }
      return credential;
    },

    async authGetOptionsServer(url, data) {
      this.loading = true;
      return await webauthn.fetch_json(url, {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
          "Content-Type": "application/json"
        },
      });
    },

    /* 获取本地电子Key相关 */
  }
};
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.login {
  display: flex;
  align-items: center;
  flex-direction: column;
  height: 100%;
  background-image: url("../assets/images/login.png");
  background-size: cover;

  .logo {
    margin: 150px 0 42px;
    height: 96px;
    width: 96px;
  }

  .login-title {
    width: 378px;
    height: 54px;
  }
}

.title {
  margin: 0px auto 30px auto;
  /*color: #707070;*/
  font-family: PangMenZhengDao;
  font-size: 32px;
  color: #333333;
  text-align: center;
  line-height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;

  .version-container {
    margin-left: 12px;
    width: 32px;
    height: 16px;
  }
}

.login-form {
  border-radius: 6px;
  margin-top: 40px;
  /*background: #ffffff;*/
  /*width: 420px;*/
  padding: 65px 50px 75px;

  .el-input {
    height: 38px;

    input {
      height: 38px;
    }
  }

  .input-icon {
    height: 39px;
    width: 14px;
    margin-left: 2px;
  }
}

.login-tip {
  font-size: 13px;
  text-align: center;
  color: #bfbfbf;
}

.login-code {
  width: 33%;
  height: 38px;
  float: right;

  img {
    cursor: pointer;
    vertical-align: middle;
  }
}

.el-login-footer {
  height: 40px;
  line-height: 40px;
  position: fixed;
  bottom: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  font-family: Arial;
  font-size: 12px;
  letter-spacing: 1px;
}

.login-code-img {
  height: 38px;
}

/*::v-deep .el-input__inner {*/
/*  border: 1px solid #18409f !important;*/
/*  color: #2f5cc6 !important;*/
/*}*/

/*::v-deep .input-icon {*/
/*  color: #2f5cc6 !important;*/
/*}*/

/*  .login-form .el-input input {
    background: #01236B !important;
    border: 1px solid #18409F !important;
    color: #2f5cc6;
  }*/

::v-deep .el-input__inner::placeholder {
  color: #2f5cc6;
}

::v-deep .el-input__inner {
  background: #01236B;
  border: 1px solid #18409F;
  color: #2f5cc6;

  &:focus {
    background-image: url("~@/assets/images/select.png");
    border: none;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    background-position: center;
    color: #FFFFFF;
  }
}
</style>
